import httplib
import threading
import Queue
import time
import sys
from Base import TaskModel, Singleton


g_ip = "123.138.163.152"
g_url_cmd = "/download?md5="
g_save_dir = "V:\\Download\\"


class SampleDownloader: 
    '''Download the Sample From TFS'''
    def __init__(self, ip = g_ip, url_cmd = g_url_cmd, savedir = g_save_dir):
        self.m_ip = ip
        self.m_url_cmd = url_cmd
        self.m_savedir = savedir
        self.__Connect()
        
    def __Connect(self,  ip = None):
        if not(ip == None) : 
            self.m_ip = ip
        self.m_http_connect = httplib.HTTPConnection(self.m_ip)
        
    def Download(self, md5, deep = 3):
        if (deep == 0):
            print "Dwonload %s fail",  md5
            return (False, None)
        try:
            self.m_http_connect.request("GET", self.m_url_cmd + md5)
            respon = self.m_http_connect.getresponse()
            if(httplib.OK == respon.status and "OK" == respon.reason):
                filedata = respon.read()
                file = open(self.m_savedir + "\\" + md5, "wb+")
                file.write(filedata)
                file.close()
                return (True, self.m_savedir + "\\" + md5)
            else:
                self.Download(md5, deep - 1)
        except (httplib.NotConnected, httplib.CannotSendRequest,
                httplib.CannotSendHeader, httplib.ResponseNotReady):
            self.__Connect()
            self.Download(md5, deep - 1)
        except (httplib.IncompleteRead, httplib.BadStatusLine):
            self.Download(md5, deep - 1)
        except (httplib.InvalidURL, httplib.UnknownProtocol, 
                httplib.UnknownTransferEncoding, httplib.UnimplementedFileMode):
            return (False, None)
        return (False, None)


class DownloadResult:
    def __init__(self, md5, bSuccess, filename):
        self.md5 = md5
        self.bSuccess = bSuccess     
        self.filename = filename

class DwonloadObserver(TaskModel.Observer):
    def OnDownloadComplete(self, md5, bSuccess, filename):
        pass

class DownloadTask(TaskModel.Task):
    def __init__(self, md5):
        TaskModel.Task.__init__(self)
        self.md5 = md5
                
class SampleDwonloadExecutor(TaskModel.Executor):
    def __init__(self):
        self.downloader = SampleDownloader()
        
    def Exec(self, task):
        bSuccess, filename = self.downloader.Download(task.md5)
        return DownloadResult(task.md5, bSuccess, filename)

class VDownloader(TaskModel.TaskModel, Singleton.Singleton):
    def __init__(self):
        TaskModel.TaskModel.__init__(self)
        
    def CreateExecutor(self):
        return SampleDwonloadExecutor()
    
    def Notify(self, observer, task, result):
        observer.OnDownloadComplete(result.md5, result.bSuccess, result.filename)

    def Download(self, md5):
        self.PostTask(DownloadTask(md5))
        
        
    def Downloads(self, md5_list):
        for md5 in md5_list:
            self.Download(md5)
      



##+--------------------------Test---------------------------+#
          

class DownloadTest(DwonloadObserver):
    def OnDownloadComplete(self, md5, bSuccess, filename):
        if bSuccess:
            resultstring = "success"
        else:
            resultstring = "fail"
        print (md5 + "\tdownload" + resultstring + "\tSaved :" + filename)
    
    def Test(self, md5_list):
        downloader = VDownloader.Instance()
        downloader.AddObserver(self)
        downloader.Start()
        downloader.Download(md5_list)
    

if __name__ == '__main__':
    tester = DownloadTest()
    md5_list = "C53DC46FBAD0C3551CFD27C10D776554"
    tester.Test(md5_list)
    


